﻿using LianChuDemo.IDal.BaseInfoManagerDal;
using Net1905CoreDemo.Common.Lib;
using Net1905CoreDemo.Common.Lib.Helper;
using Net1905CoreDemo.Common.Lib.TextTools;
using Net1905CoreDemo.ViewModel.BaseInfoManagerView;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WenDangOne.Common.Lib.TextTools;
using WenDangOne.Common.Lib.TypeTools;
using WenDangOne.DbModel.BaseInfoManager;
using WenDangOne.ViewModel.BaseInfoManagerView;
using WenDangOne.ViewModel.common;
using Microsoft.AspNetCore.Http;
using WenDangOne.Common.Lib;

namespace LianChuDemo.Bll.BaseInfoManagerBll
{
    public class AdminUserBll
    {
        private IAdminUserDal _iAdminUserDal;
        private RoleDbBll _roleBll;
        //这里注入
        private ModuleDbBll _moduleDbBll;

        public AdminUserBll(IAdminUserDal iAdminUserDal, RoleDbBll roleBll, ModuleDbBll moduleDbBll)
        {
            _iAdminUserDal = iAdminUserDal;
            _roleBll = roleBll;
            _moduleDbBll = moduleDbBll;
        }
         
        public PagerResult<AdminUser> SearchPage(SearchModel searchModel)
        {
            return _iAdminUserDal.SearchPage(searchModel);
        }
        //刚写过来的时候是报错的，说要转换成静态，但是只要写上里面的内容就可以了
        public bool AdminUserAdd(AdminUserView view)
        {
            view.pass_word = StringMd5.Md5Hash32Salt(view.pass_word);
            return _iAdminUserDal.AdminUserAdd(view);
        }
        public AdminUser GetAdminUserByUserName(string userName)
        {
            return _iAdminUserDal.GetAdminUserByUserName(userName);
        }

        //public bool VAdmminUserName(string userName)
        //{
        //    if (_iAdminUserDal.GetAdminUserByUserName(userName) == null) return true;
        //    return false;
        //}下面简写

        public bool VAdmminUserName(string userName)
        {
            if (GetAdminUserByUserName(userName) == null) return true;
            return false;
        }
        public bool AdminUserUpdate(AdminUserView view)
        {
            return _iAdminUserDal.AdminUserUpdate(view);
        }

        public AdminUserView GetAdminUserViewByUserName(string userName)
        {
            return _iAdminUserDal.GetAdminUserViewByUserName(userName);
        }
        public bool AdminUserPwdUpdate(string pwd, string userName)
        {
            pwd= StringMd5.Md5Hash32Salt(pwd);
            return _iAdminUserDal.AdminUserPwdUpdate(pwd, userName);
        }

        //带进来.login生成
        /// <summary>
        /// 登录用户初始化
        /// </summary>
        /// <param name="adminUserView"></param>
        /// <returns></returns>
        public LoginUser LoginBuild(AdminUserView adminUserView)
        {
            //
            //客户token，服务login
            //申明一个对象
            LoginJwtObj ljo = new LoginJwtObj()
            {
                UserName = adminUserView.user_name,
                LoginDate = DateTime.Now
            };
            //此处是加密，加密出一个串然后写入Redis 这里参数？这里是生成口令
            string token = JwtUtil.Encode(ljo);
            //把信息放到loginUser
            LoginUser loginUser = new LoginUser();
            //存进token里头
            loginUser.Token = token;
            //将前面的model拷到后面的model里，相当于缓存，随取随拿，存储数据的地方
            ModelCopier.CopyModel(adminUserView, loginUser);
            //这里需要注入,没有根据用户来获取角色，所以要在IRoleDb里头加，然后根据name进行一个查找
            //初始化登录用户下的所有角色
            loginUser.Roles = _roleBll.GetRoleDbsByUserName(loginUser.user_name);
            //初始化登陆用户下的所有的权限
            loginUser.ModelCodes = _moduleDbBll.GetModuleDbsByUserName(loginUser.user_name).Select(p => p.module_code).ToList();
            //在里面保存1200秒然后过期(调用下面的方法）
            LoginBulidSetRedis(loginUser);
            return loginUser;

        }
        public void LoginBulidSetRedis(LoginUser loginUser)
        {
            //在里面保存1200秒然后过期，用的就是用户名，存进去的就是用户名和密码，所以这里是用用户名
            MyRedisHelper.Set(loginUser.user_name, loginUser, 1200);
        }
        public LoginUser Login(string userName, string passWord, out string mess)
        {
            //判断输入的名字是否为空，为空就返回空，同时提示参数错误
            if(string.IsNullOrWhiteSpace(userName))
            {
                mess = "参数错误";
                return null;
            }
            //判断输入的密码是否为空，为空就返回空，同时提示参数错误
            if (string.IsNullOrWhiteSpace(passWord))
            {
                mess = "参数错误";
                return null;
            }
            //这里调用的是上面的一个方法，那个方法查的就是由name查询单挑数据，list集合，所以这里是在调用，根据名称查询数据
            AdminUserView adminUserView = _iAdminUserDal.GetAdminUserViewByUserName(userName);
            //由用户名查找集合，如果这个集合里头是空的那就说明没有这个用户，是输入错误了
            if(adminUserView==null)
            {
                mess = "用户名不正确";
                return null;
            }
            //这里是给你输入的密码一个加密
            passWord = StringMd5.Md5Hash32Salt(passWord);
            //进行一个判断，如果输入的密码加密之后不等于数据库里头的，那就是你写错了
            if(adminUserView.pass_word!=passWord)
            {
                mess = "密码错误";
                return null;
            }
            mess = "登录成功";
            //进行下一步操作，login的操作
            return LoginBuild(adminUserView);
        }

        //刷新过期的时间
        public bool VToken(string token)
        {
            //先判断是否为空，为空肯定是验证不通过的。为什么这里要写验证，因为有可能不一定是过滤器调用，也有可能其他地方也会调用。
            if (string.IsNullOrWhiteSpace(token)) return false;
            //调用下面的方法，对token进行一个对比。
            LoginUser user = GetLoginUserInRedisByToken(token);
            if (user != null)
            {
                LoginBulidSetRedis(user); //刷新过期时间
                return true;
            }
            return false;
        }

        //这个也有可能是多地方调
        public LoginUser GetLoginUserInRedisByToken(string token)
        {
            //判断不为空
            if (string.IsNullOrWhiteSpace(token)) return null;
            //然后再对token进行解密
            LoginJwtObj loginJwtObj = JwtUtil.Decode<LoginJwtObj>(token);
            //如果解密失败，那么这个token是假的，错误的
            if (loginJwtObj == null) return null;
            //解密成功，就把token这个相应的内容用用户名最为id提出来，因为用户名就是存进去的
            LoginUser user = MyRedisHelper.Get<LoginUser>(loginJwtObj.UserName);
            return user;
        }

        //封装一个登录，获取当前登录的对象和时间
        public static string GetTokenInHeader()
        {
            //IHttpContextAccessor  获取当前登录的对象
            var IHttpContextAccessor =  DiManager.GetDiObj<IHttpContextAccessor>();
            //就是获取token
            Microsoft.Extensions.Primitives.StringValues token;
            if (IHttpContextAccessor.HttpContext.Request.Headers.TryGetValue("X-Token", out token)) //获取token
            {
                return token;
            }
            return null;
        }
        public static LoginUser GetLoginUser()
        {
            //获取token
            string token = GetTokenInHeader();
            //判断他这里是否为空，然后根据这个获取token
            if (string.IsNullOrWhiteSpace(token)) return null; 
            AdminUserBll bll = DiManager.GetDiObjScoped<AdminUserBll>();
            //不为null我们可以根据token获取登录的数据
            return bll.GetLoginUserInRedisByToken(token);
        }
    }
}
